home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / pixmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.9 KB  |  341 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18. ** $Revision: 1.2 $
  19. ** $Date: 1994/02/22 23:31:29 $
  20. */
  21. /*
  22. **  This program is to demonstrate the use of OpenGL with both X windows
  23. **  and pixmaps.  One context is shared between a pixmap and a window.
  24. **  Note that since the default is to render to the pixmap, no image will
  25. **  be drawn in the window when it first comes up.
  26. **
  27. **  The picture consists of three triangles clipped and
  28. **  layered using depth and scissor tests.
  29. **
  30. **  The user controls rendering with three keys:
  31. **    w    Render to the window 
  32. **    p    Render to the pixmap (default)
  33. **    c    Copy the contents of the pixmap into the window
  34. **
  35. **  The program runs in rgb mode by default.  To run in color index mode,
  36. **  use the command line option -c.
  37. */
  38.  
  39. #include <GL/glx.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <X11/keysym.h>
  43.  
  44. static int RGBattributes[] = {
  45.     GLX_RGBA,
  46.     GLX_RED_SIZE, 1,
  47.     GLX_GREEN_SIZE, 1,
  48.     GLX_BLUE_SIZE, 1,
  49.     None,
  50. };
  51.  
  52. static int CIattributes[] = {
  53.     GLX_DEPTH_SIZE, 1,
  54.     None,
  55. };
  56.  
  57. int width = 200, height = 200;
  58.  
  59. static void Reshape(int w, int h)
  60. {
  61.     glViewport(0, 0, (GLint)w, (GLint)h);
  62.  
  63.     width = w;
  64.     height = h;
  65.  
  66.     glMatrixMode(GL_PROJECTION);
  67.     glLoadIdentity();
  68.     glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
  69.     glMatrixMode(GL_MODELVIEW);
  70. }
  71.  
  72.  
  73. static void Init(void)
  74. {
  75.  
  76.     glClearColor(0.0, 0.0, 0.0, 0.0);
  77.     glClearIndex(1.0);
  78.  
  79.     glClearDepth(1);
  80.     glClearStencil(0);
  81.     glEnable(GL_DEPTH_TEST);
  82. }
  83.  
  84.  
  85.  
  86. static void DoDisplay(void)
  87. {
  88.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  89.  
  90.     glColor3ub(200, 0, 0);
  91.     glIndexi(2);
  92.     glBegin(GL_POLYGON);
  93.         glVertex3i(-4, -3, -2);
  94.         glVertex3i( 4, -3, -2);
  95.         glVertex3i( 0,  4, -2);
  96.     glEnd();
  97.     glFlush();
  98.  
  99.     glEnable(GL_SCISSOR_TEST);
  100.     glScissor(width/3, height/3, width/3, height/3);
  101.     glColor3ub(0, 200, 0);
  102.     glIndexi(29);
  103.     glBegin(GL_POLYGON);
  104.         glVertex3i(-4, -3, 0);
  105.         glVertex3i( 4, -3, 0);
  106.         glVertex3i( 0,  4, 0);
  107.     glEnd();
  108.     glDisable(GL_SCISSOR_TEST);
  109.     glFlush();
  110.  
  111.     glColor3ub(0, 0, 200);
  112.     glIndexi(31);
  113.     glBegin(GL_POLYGON);
  114.         glVertex3i(-4, -4, -1);
  115.         glVertex3i( 4, -4, -1);
  116.         glVertex3i( 0,  3, -1);
  117.     glEnd();
  118.     glFlush();
  119.  
  120. }
  121.  
  122.  
  123. static void Usage(void)
  124. {
  125.     printf("Usage: pixmap [-c]\n");
  126.     printf("   -c:  Run in color index mode\n");
  127.     exit(-1);
  128. }
  129.  
  130.  
  131. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  132. {
  133.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  134.     return GL_TRUE;
  135.     }
  136.     return GL_FALSE;
  137. }
  138.  
  139. int main(int argc, char *argv[])
  140. {
  141.     /* X variables */
  142.     XVisualInfo *vi;
  143.     Display *dpy;
  144.     Colormap cmap;
  145.     Window window;
  146.     Window root;
  147.     Pixmap pixmap;
  148.     XSetWindowAttributes swa;
  149.     XEvent event;
  150.     GC gc;
  151.  
  152.     /* GLX variables */
  153.     GLXContext cx;
  154.     GLXPixmap pm;
  155.  
  156.     GLboolean needDisplay;
  157.     int gx, gy, i;
  158.     unsigned int gwidth, gheight, gborder_width, gdepth;
  159.     Status xggStatus;
  160.     int rgb = 1;    /* Use rgb mode by default */
  161.  
  162.     /*
  163.     ** Read command line arguments.
  164.     */
  165.     for (i = 1; i < argc; i++) {
  166.         if (argv[i][0] == '-') {
  167.             switch (argv[i][1]) {
  168.               case 'c':
  169.                 rgb = 0;
  170.                 break;
  171.               default:
  172.                 Usage();
  173.             }
  174.         } else {
  175.             Usage();
  176.         }
  177.     }
  178.  
  179.  
  180.     /*
  181.     ** Open the X connection.
  182.     */
  183.     dpy = XOpenDisplay(0);
  184.     if (!dpy) {
  185.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  186.     return -1;
  187.     }
  188.  
  189.     /*
  190.     ** Select the X visual enabled for OpenGL, using RGB or CI mode.
  191.     */
  192.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), 
  193.         rgb ? RGBattributes : CIattributes);
  194.     if (!vi) {
  195.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  196.         getenv("DISPLAY"));
  197.     return -1;
  198.     }
  199.  
  200.     /*
  201.     ** Create a colormap.
  202.     ** If its RGB, then the visual is TrueColor and the map is already
  203.     ** allocated read-only.  For CI, allocate the entire map.
  204.     */
  205.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  206.                rgb ? AllocNone: AllocAll);
  207.     /* XXX 
  208.     ** could use some colormap setting here.
  209.     */
  210.  
  211.     /* 
  212.     ** Set the window attributes in the  XSetWindowAttributes structure.
  213.     ** Ask for events at exposure, change in window structure, key
  214.     ** presses.
  215.     */
  216.     swa.border_pixel = 0;
  217.     swa.colormap = cmap;
  218.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  219.     | KeyReleaseMask;
  220.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
  221.                width, height,
  222.                0, vi->depth, InputOutput, vi->visual,
  223.                CWBorderPixel|CWColormap|CWEventMask, &swa);
  224.     XSetStandardProperties(dpy, window, "pixmap", "pixmap", None, argv, argc, 
  225.     NULL);
  226.     XSetWMColormapWindows(dpy, window, &window, 1);
  227.  
  228.     /*
  229.     ** Make the window visible by mapping it.
  230.     */
  231.     XMapWindow(dpy, window);
  232.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  233.  
  234.     /*
  235.     ** Create an X graphics context.
  236.     */
  237.     gc = XCreateGC(dpy, window, 0, NULL);
  238.  
  239.     /*
  240.     **  Create a pixmap, using the same depth as the window visual.
  241.     **  Next, create a a GLX rendering area using that pixmap.
  242.     */
  243.     pixmap = XCreatePixmap(dpy, RootWindow(dpy, vi->screen), 
  244.     width, height, vi->depth);
  245.     pm = glXCreateGLXPixmap(dpy, vi, pixmap);
  246.     xggStatus = XGetGeometry(dpy, pixmap, &root, &gx, &gy, &gwidth, &gheight,
  247.     &gborder_width, &gdepth);
  248.  
  249.     /*
  250.     ** Create an OpenGL context, and make it current to the pixmap.
  251.     */
  252.     cx = glXCreateContext(dpy, vi, 0, GL_FALSE);
  253.     if (!glXMakeCurrent(dpy, pm, cx)) {
  254.     fprintf(stderr, "Can't make pixmap current to context\n");
  255.     return -1;
  256.     }
  257.  
  258.  
  259.     printf("rendering to pixmap\n");
  260.     Init();
  261.  
  262.     needDisplay = GL_TRUE;
  263.  
  264.     /*
  265.     ** Main event loop
  266.     */
  267.     for (;;) {
  268.     do {
  269.         XNextEvent(dpy, &event);
  270.         switch (event.type) {
  271.           case Expose:
  272.         needDisplay = GL_TRUE;
  273.         break;
  274.           case ConfigureNotify:
  275.         width = event.xconfigure.width;
  276.         height = event.xconfigure.height;
  277.         Reshape(width, height);
  278.         needDisplay = GL_TRUE;
  279.         break;
  280.           case KeyPress:
  281.         {
  282.             char buf[100];
  283.             int rv;
  284.             KeySym ks;
  285.  
  286.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  287.             switch (ks) {
  288.  
  289.               case XK_c:
  290.             /*
  291.             ** Copy pixmap into window.
  292.             */
  293.             xggStatus = XGetGeometry(dpy, window, &root, &gx, &gy, 
  294.                 &gwidth, &gheight, &gborder_width, &gdepth);
  295.             XCopyArea(dpy, pixmap, window, gc, 0, 0, gwidth,
  296.                 gheight, gx, gy);
  297.             printf("copying the pixmap into the window\n");
  298.             break;
  299.  
  300.               case XK_p:
  301.             /*
  302.             ** Make the pixmap the current rendering target.
  303.             */
  304.             glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  305.             if (!glXMakeCurrent(dpy, pm, cx)) {
  306.                 fprintf(stderr, 
  307.                    "Can't make pixmap current to context\n");
  308.                 return -1;
  309.             }
  310.             needDisplay = GL_TRUE;
  311.             printf("rendering to pixmap\n");
  312.             break;
  313.  
  314.               case XK_w:
  315.             /*
  316.             ** Make the window the current rendering target.
  317.             */
  318.             if (!glXMakeCurrent(dpy, window, cx)) {
  319.                 fprintf(stderr, 
  320.                    "Can't make window current to context\n");
  321.                 return -1;
  322.             }
  323.             needDisplay = GL_TRUE;
  324.             printf("rendering to window\n");
  325.             break;
  326.               case XK_Escape:
  327.             return 0;
  328.             }
  329.         }
  330.         break;
  331.         }
  332.     } while (XPending(dpy) != 0);
  333.  
  334.     if (needDisplay) {
  335.         needDisplay = GL_FALSE;
  336.         DoDisplay();
  337.         glFlush();
  338.     }
  339.     }
  340. }
  341.